/**************************************************************************************
*  UART.c
*
*  This file defines all native methods that have to be implemented to support
*  the class lpc2xxx/comm/UART
*
*  Application developer should use the following functions to get access to
*  arrays and String object:
*       vmGetStringCount
*       vmGetStringArray
*       vmGetArraySize
*       vmGetArray
*  These functions are accessible via vm_config_t structure.
*
*  Native methods implementation
*  -----------------------------
*  Note that if the native method is NOT declared as static then param[0]
*  contains object's reference and must be skiped when accessing the native
*  method parameters.
**************************************************************************************
*
* This file is covered by the GNU GPL with the following exception:
*   As a special exception, the copyright holders of this library give you permission
*   to link this library with independent modules to produce an executable, regardless
*   of the license terms of these independent modules, and to copy and distribute the
*   resulting executable under terms of your choice, provided that you also meet, for
*   each linked independent module, the terms and conditions of the license of that
*   module. An independent module is a module which is not derived from or based on
*   this library. If you modify this library, you may extend this exception to your
*   version of the library, but you are not obligated to do so. If you do not wish
*   to do so, delete this exception statement from your version.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL RTJ COMPUTING BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Copyright (c) 2000-2006 RTJ Computing Pty. Ltd. All rights reserved.
**************************************************************************************/
#include <lpc2xxx.h>
#include "uart.h"

#include "javavm.h"

extern vm_config_t vmconfig;
extern uart_t uart0, uart1;

/****************************************************************************
* Opens the specified serial port.
* On entry: param[1] - port number (0=UART0, 1=UART1)
*           param[2] - baud rate (1200 - 115200)
*           param[3] - number of bits (0=5 bits, 1=6 bits, 2=7 bits, 3=8 bits)
*           param[4] - parity (None: 0x00, Odd: 0x08 or Even: 0x18)
*           param[5] - stop bits (0=1 stop, 4=2 stop)
* On return function returns true if successful via retval parameter.
*
* Java prototype:
*   private native boolean open0(int port, int baud, int bits, int parity, int stop);
*
****************************************************************************/
int16 lpc2xxx_comm_UART_open0(int32 param[], int32 *retval)
{
    tU16 div = B1200((CRYSTAL_FREQUENCY * PLL_FACTOR) / VPBDIV_FACTOR);;
    tU8 mode;
    uart_t *uart;

    *retval = true;
    switch (param[2]) {
        case   2400: div =   B2400((CRYSTAL_FREQUENCY * PLL_FACTOR) / VPBDIV_FACTOR); break;
        case   9600: div =   B9600((CRYSTAL_FREQUENCY * PLL_FACTOR) / VPBDIV_FACTOR); break;
        case  19200: div =  B19200((CRYSTAL_FREQUENCY * PLL_FACTOR) / VPBDIV_FACTOR); break;
        case  38400: div =  B38400((CRYSTAL_FREQUENCY * PLL_FACTOR) / VPBDIV_FACTOR); break;
        case  57600: div =  B57600((CRYSTAL_FREQUENCY * PLL_FACTOR) / VPBDIV_FACTOR); break;
        case 115200: div = B115200((CRYSTAL_FREQUENCY * PLL_FACTOR) / VPBDIV_FACTOR); break;
        default:
            *retval = false;
    }
    mode = (tU8)(param[3] | param[4] | param[5]);

    if (*retval) {
        if (param[1] == 0) {
            uart = &uart0;
            uart0.uartRegBase = UART0_REG_BASE;
        }
        else {
            uart = &uart1;
            uart1.uartRegBase = UART1_REG_BASE;
        }
        initUart(uart, div, mode, UART_FIFO_OFF);
    }
    return NO_EXCEP;
}

/****************************************************************************
* Closes the specified serial port.
* On entry: param[1] - port number (0=UART0, 1=UART1)
*
* Java prototype:
*   private native void close0(int port);
*
****************************************************************************/
int16 lpc2xxx_comm_UART_close0(int32 param[], int32 *retval)
{
    if (param[1] == 0) {
        // disable UART0 interrupts
        REG(uart0.uartRegBase + UIER) = 0;
        // disable interrupts in VIC
        VICVectAddr6  = 0;    
        VICIntEnable &= ~0x00000040;
    }
    else {
        // disable UART1 interrupts
        REG(uart1.uartRegBase + UIER) = 0;
        // disable interrupts in VIC
        VICVectAddr7  = 0;
        VICIntEnable &= ~0x00000080;
    }
    return NO_EXCEP;
}

/****************************************************************************
* Reads one byte from serial port. Waits if not available.
* On entry: param[1] - port number (0=UART0, 1=UART1)
* On return function sets the retval parameter to the received byte.
*
* Java prototype:
*   private native byte read0(int port);
*
****************************************************************************/
int16 lpc2xxx_comm_UART_read0(int32 param[], int32 *retval)
{
    uart_t *uart;

	uart = (param[1] == 0) ? &uart0 : &uart1;
    *retval = uartGetCh(uart);

    return NO_EXCEP;
}

/****************************************************************************
* Writes one byte to the serial port.
* On entry: param[1] - port number (0=UART0, 1=UART1)
*           param[2] - byte to be written
*
* Java prototype:
*   private native void write0(int port, byte value);
*
****************************************************************************/
int16 lpc2xxx_comm_UART_write0(int32 param[], int32 *retval)
{
    uart_t *uart;

	uart = (param[1] == 0) ? &uart0 : &uart1;
    uartSendChar(uart, (tU8)param[2]);

    return NO_EXCEP;
}

/****************************************************************************
* Returns the status of the specified port
* On entry: param[1] - port number (0=UART0, 1=UART1)
* On return function provides the status of LS register via retval parameter.
*
* Java prototype:
*   private native int getStatus0(int port)
*
****************************************************************************/
int16 lpc2xxx_comm_UART_getStatus0(int32 param[], int32 *retval)
{
    uart_t *uart;

	uart = (param[1] == 0) ? &uart0 : &uart1;
    *retval = REG(uart->uartRegBase + ULSR);

    return NO_EXCEP;
}

/****************************************************************************
* Purges Rx and Tx buffers on specified port.
* On entry: param[1] - port number (0=UART0, 1=UART1)
*
* Java prototype:
*   private native void purge0(int port)
*
****************************************************************************/
int16 lpc2xxx_comm_UART_purge0(int32 param[], int32 *retval)
{
    uart_t *uart;

	uart = (param[1] == 0) ? &uart0 : &uart1;
    uartPurge(uart);
    return NO_EXCEP;
}

/****************************************************************************
* Checks if a character is available for reading.
* On entry: param[1] - port number (0=UART0, 1=UART1)
* On return function indicate whether character(s) is available via
* retval parameter.
*
* Java prototype:
*   private native boolean dataAvail(int port)
*
****************************************************************************/
int16 lpc2xxx_comm_UART_dataAvail(int32 param[], int32 *retval)
{
    uart_t *uart;

	uart = (param[1] == 0) ? &uart0 : &uart1;
    *retval = uartCharAvail(uart);
    return NO_EXCEP;
}



